package com.sharp.core.math;

import com.sharp.core.math.primitives.Object3D;

/**
The Vector3D class implements a 3D vector with the
floating-point values x, y, and z. Vectors can be thought of
either as a (x,y,z) point or as a vector from (0,0,0) to
(x,y,z).
*/
public final class Vec3 extends UnVec3 {
	
	/**
	    Creates a new Vector3D at (0,0,0).
	*/
	public Vec3() {
	    
	}
	
	public Vec3(Object3D from, Object3D to) {
		this(from.getPos(), to.getPos());
	}

	
	public Vec3(UnVec3 from, UnVec3 to) {
		this( to.x - from.x, to.y - from.y, to.z - from.z );
	}
	
	
	/**
	    Creates a new Vector3D with the same values as the
	    specified Vector3D.
	*/
	public Vec3(UnVec3 v) {
	    this(v.x, v.y, v.z);
	}
	
	
	/**
	    Creates a new Vector3D with the specified (x, y, z) values.
	*/
	public Vec3(float x, float y, float z) {
	    setTo(x, y, z);
	}
	
	/**
	    Checks if this Vector3D is equal to the specified Object.
	    They are equal only if the specified Object is a Vector3D
	    and the two Vector3D's x, y, and z coordinates are equal.
	*/
	public final boolean equals(Object obj) {
		UnVec3 v = (UnVec3)obj;
	    return (v.x == x && v.y == y && v.z == z);
	}
	
	
	/**
	    Checks if this Vector3D is equal to the specified
	    x, y, and z coordinates.
	*/
	public final boolean equals(float x, float y, float z) {
	    return (this.x == x && this.y == y && this.z == z);
	}
	
	public final void setTo(UnVec3 from, UnVec3 to) {
		setTo( to.x - from.x, to.y - from.y, to.z - from.z );
	}

	/**
	    Sets the vector to the same values as the specified
	    Vector3D.
	*/
	public final void setTo(UnVec3 v) {
	    setTo(v.x, v.y, v.z);
	}
	
	
	/**
	    Sets this vector to the specified (x, y, z) values.
	*/
	public final void setTo(float x, float y, float z) {
	    this.x = x;
	    this.y = y;
	    this.z = z;
	}
	
	
	/**
	    Adds the specified (x, y, z) values to this vector.
	*/
	public final Vec3 add(float x, float y, float z) {
	    this.x+=x;
	    this.y+=y;
	    this.z+=z;
	    return this;
	}
	
	
	/**
	    Subtracts the specified (x, y, z) values to this vector.
	*/
	public final Vec3 subtract(float x, float y, float z) {
	    add(-x, -y, -z);
	    return this;
	}
	
	
	/**
	    Adds the specified vector to this vector.
	*/
	public final Vec3 add(UnVec3 v) {
	    add(v.x, v.y, v.z);
	    return this;
	}
	
	
	/**
	    Subtracts the specified vector from this vector.
	*/
	public final Vec3 subtract(UnVec3 v) {
	    add(-v.x, -v.y, -v.z);
	    return this;
	}
	
	
	/**
	    Multiplies this vector by the specified value. The new
	    length of this vector will be length()*s.
	*/
	public final Vec3 multiply(float s) {
	   x*=s;
	   y*=s;
	   z*=s;
	   return this;
	}
	
	
	/**
	    Divides this vector by the specified value. The new
	    length of this vector will be length()/s.
	*/
	public final Vec3 divide(float s) {
	   x/=s;
	   y/=s;
	   z/=s;
	   return this;
	}
	
	
	/**
	    Converts this Vector3D to a unit vector, or, in other
	    words, a vector of length 1. Same as calling
	    v.divide(v.length()).
	*/
	public final Vec3 normalize() {
	    return divide(length());
	}
	
	

	public final void setX(float x) {
		this.x = x;
	}


	public final void setY(float y) {
		this.y = y;
	}

	public final void setZ(float z) {
		this.z = z;
	}
	
	
}
